#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#include "debug.h"
#include "os_api.h"


#define _STACK_1_SIZE			0x2000
#define _STACK_2_SIZE			0x2000
static void* _task_1_stack = NULL;
static void* _task_2_stack = NULL;

static OSTaskRef _task_1_ref = NULL;
static OSTaskRef _task_2_ref = NULL;

static OSSemaRef testSemaRef = NULL;

OSATimerRef _task_1_delete_timer_ref = NULL;

void DeleteTask1ByTimer(UINT32 id)
{
    OSA_STATUS status;

    if(_task_1_ref)
    {
        status = OSATaskDelete(_task_1_ref);
        ASSERT(status == OS_SUCCESS);
        _task_1_ref = NULL;
	   
        if(_task_1_stack)
        {
            free(_task_1_stack);
            _task_1_stack = NULL;
        }
    }

    OSATimerDelete (_task_1_delete_timer_ref);
}


static void _task_1(void *ptr)
{
	int count = 1;
    OSA_STATUS status;
	
	while(count++ < 100){
	
		LOG_PRINTF("**this is a _task_1 count %d\n", count);
		if (count == 20){

			status = OSASemaphoreAcquire(testSemaRef, OS_SUSPEND);
    		ASSERT(status == OS_SUCCESS);
			LOG_PRINTF("**this is a _task_1 count %d**\n", count);
			OSATaskSleep(5);
			LOG_PRINTF("**this is a _task_1 count %d**\n", count);
			OSATaskSleep(5);
			LOG_PRINTF("**this is a _task_1 count %d**\n", count);
			OSATaskSleep(5);
			LOG_PRINTF("**this is a _task_1 count %d**\n", count);
			OSATaskSleep(5);
			LOG_PRINTF("**this is a _task_1 count %d**\n", count);
			OSATaskSleep(5);
			LOG_PRINTF("**this is a _task_1 count %d**\n", count);
			OSATaskSleep(5);
			LOG_PRINTF("**this is a _task_1 count %d**\n", count);
			OSATaskSleep(5);
			LOG_PRINTF("**this is a _task_1 count %d**\n", count);
			OSATaskSleep(5);
			LOG_PRINTF("**this is a _task_1 count %d**\n", count);
			OSATaskSleep(5);
			LOG_PRINTF("**this is a _task_1 count %d**\n", count);
			status = OSASemaphoreRelease(testSemaRef);
			ASSERT(status == OS_SUCCESS);			
		}
		OSATaskSleep(5);		// 如果可能存在while空跑的case，一定需要加上个sleep，不然可能会造成系统调度异常
	}
	
	OSATimerCreate(&_task_1_delete_timer_ref);
	OSATimerStart(_task_1_delete_timer_ref, 400, 0, DeleteTask1ByTimer, 0);
}


static void _task_2(void *ptr)
{
	int count = 1;
	OSA_STATUS status;
	
	while(count++ < 1000){
		status = OSASemaphoreAcquire(testSemaRef, OS_SUSPEND);
		ASSERT(status == OS_SUCCESS);		
		LOG_PRINTF("##this is a _task_2 count %d\n", count);
		OSATaskSleep(5);
		status = OSASemaphoreRelease(testSemaRef);
		ASSERT(status == OS_SUCCESS);			
	}

}


int main(void)
{	
     OSA_STATUS status;

	_task_1_stack = malloc(_STACK_1_SIZE);
    ASSERT(_task_1_stack != NULL);
	_task_2_stack = malloc(_STACK_2_SIZE);
    ASSERT(_task_2_stack != NULL);
	
	status = OSASemaphoreCreate (&testSemaRef, 1, OSA_FIFO);
    ASSERT(status == OS_SUCCESS);

    status = OSATaskCreate(&_task_1_ref, _task_1_stack, _STACK_1_SIZE, 100, "_task_1", _task_1, NULL);
    ASSERT(status == OS_SUCCESS);
	
    status = OSATaskCreate(&_task_2_ref, _task_2_stack, _STACK_2_SIZE, 101, "_task_2", _task_2, NULL);
    ASSERT(status == OS_SUCCESS);	
	
	return 0;
}